{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# -*- coding: iso-8859-15 -*-\n",
    "############Linear Algebra From DSScratch chp4 Line Alg\n",
    "import re, math, random # regexes, math functions, random numbers\n",
    "import matplotlib.pyplot as plt # pyplot\n",
    "from collections import defaultdict, Counter\n",
    "from functools import partial, reduce\n",
    "%matplotlib inline\n",
    "#\n",
    "# functions for working with vectors\n",
    "#\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# functions for working with vectors\n",
    "#\n",
    "\n",
    "def vector_add(v, w):\n",
    "    \"\"\"adds two vectors componentwise\"\"\"\n",
    "    return [v_i + w_i for v_i, w_i in zip(v,w)]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def vector_subtract(v, w):\n",
    "    \"\"\"subtracts two vectors componentwise\"\"\"\n",
    "    return [v_i - w_i for v_i, w_i in zip(v,w)]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def vector_sum(vectors):\n",
    "    return reduce(vector_add, vectors)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def scalar_multiply(c, v):\n",
    "    return [c * v_i for v_i in v]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def vector_mean(vectors):\n",
    "    \"\"\"compute the vector whose i-th element is the mean of the\n",
    "    i-th elements of the input vectors\"\"\"\n",
    "    n = len(vectors)\n",
    "    return scalar_multiply(1/n, vector_sum(vectors))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def dot(v, w):\n",
    "    \"\"\"v_1 * w_1 + ... + v_n * w_n\"\"\"\n",
    "    return sum(v_i * w_i for v_i, w_i in zip(v, w))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def sum_of_squares(v):\n",
    "    \"\"\"v_1 * v_1 + ... + v_n * v_n\"\"\"\n",
    "    return dot(v, v)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def magnitude(v):\n",
    "    return math.sqrt(sum_of_squares(v))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def squared_distance(v, w):\n",
    "    return sum_of_squares(vector_subtract(v, w))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def distance(v, w):\n",
    "   return math.sqrt(squared_distance(v, w))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# functions for working with matrices\n",
    "#\n",
    "\n",
    "def shape(A):\n",
    "    num_rows = len(A)\n",
    "    num_cols = len(A[0]) if A else 0\n",
    "    return num_rows, num_cols\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def get_row(A, i):\n",
    "    return A[i]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def get_column(A, j):\n",
    "    return [A_i[j] for A_i in A]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def make_matrix(num_rows, num_cols, entry_fn):\n",
    "    \"\"\"returns a num_rows x num_cols matrix\n",
    "    whose (i,j)-th entry is entry_fn(i, j)\"\"\"\n",
    "    return [[entry_fn(i, j) for j in range(num_cols)]\n",
    "            for i in range(num_rows)]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def is_diagonal(i, j):\n",
    "    \"\"\"1's on the 'diagonal', 0's everywhere else\"\"\"\n",
    "    return 1 if i == j else 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "identity_matrix = make_matrix(5, 5, is_diagonal)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#          user 0  1  2  3  4  5  6  7  8  9\n",
    "#\n",
    "friendships = [[0, 1, 1, 0, 0, 0, 0, 0, 0, 0], # user 0\n",
    "               [1, 0, 1, 1, 0, 0, 0, 0, 0, 0], # user 1\n",
    "               [1, 1, 0, 1, 0, 0, 0, 0, 0, 0], # user 2\n",
    "               [0, 1, 1, 0, 1, 0, 0, 0, 0, 0], # user 3\n",
    "               [0, 0, 0, 1, 0, 1, 0, 0, 0, 0], # user 4\n",
    "               [0, 0, 0, 0, 1, 0, 1, 1, 0, 0], # user 5\n",
    "               [0, 0, 0, 0, 0, 1, 0, 0, 1, 0], # user 6\n",
    "               [0, 0, 0, 0, 0, 1, 0, 0, 1, 0], # user 7\n",
    "               [0, 0, 0, 0, 0, 0, 1, 1, 0, 1], # user 8\n",
    "               [0, 0, 0, 0, 0, 0, 0, 0, 1, 0]] # user 9\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# DELETE DOWN\n",
    "#\n",
    "\n",
    "\n",
    "def matrix_add(A, B):\n",
    "    if shape(A) != shape(B):\n",
    "        raise ArithmeticError(\"cannot add matrices with different shapes\")\n",
    "\n",
    "    num_rows, num_cols = shape(A)\n",
    "    def entry_fn(i, j): return A[i][j] + B[i][j]\n",
    "\n",
    "    return make_matrix(num_rows, num_cols, entry_fn)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "def make_graph_dot_product_as_vector_projection(plt):\n",
    "\n",
    "    v = [2, 1]\n",
    "    w = [math.sqrt(.25), math.sqrt(.75)]\n",
    "    c = dot(v, w)\n",
    "    vonw = scalar_multiply(c, w)\n",
    "    o = [0,0]\n",
    "\n",
    "    plt.arrow(0, 0, v[0], v[1],\n",
    "              width=0.002, head_width=.1, length_includes_head=True)\n",
    "    plt.annotate(\"v\", v, xytext=[v[0] + 0.1, v[1]])\n",
    "    plt.arrow(0 ,0, w[0], w[1],\n",
    "              width=0.002, head_width=.1, length_includes_head=True)\n",
    "    plt.annotate(\"w\", w, xytext=[w[0] - 0.1, w[1]])\n",
    "    plt.arrow(0, 0, vonw[0], vonw[1], length_includes_head=True)\n",
    "    plt.annotate(u\"(v•w)w\", vonw, xytext=[vonw[0] - 0.1, vonw[1] + 0.1])\n",
    "    plt.arrow(v[0], v[1], vonw[0] - v[0], vonw[1] - v[1],\n",
    "              linestyle='dotted', length_includes_head=True)\n",
    "    plt.scatter(*zip(v,w,o),marker='.')\n",
    "    plt.axis('equal')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fe4135bcda0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#if __name__ == \"__main__\":\n",
    "\n",
    "make_graph_dot_product_as_vector_projection(plt)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "############Statistic From DSScratch chp5 Stats\n",
    "from collections import Counter\n",
    "#from linear_algebra import sum_of_squares, dot\n",
    "import math\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import re, math, random # regexes, math functions, random numbers\n",
    "import matplotlib.pyplot as plt # pyplot\n",
    "from collections import defaultdict, Counter\n",
    "from functools import partial, reduce\n",
    "\n",
    "#\n",
    "# functions for working with vectors\n",
    "#\n",
    "\n",
    "def vector_add(v, w):\n",
    "    \"\"\"adds two vectors componentwise\"\"\"\n",
    "    return [v_i + w_i for v_i, w_i in zip(v,w)]\n",
    "\n",
    "def vector_subtract(v, w):\n",
    "    \"\"\"subtracts two vectors componentwise\"\"\"\n",
    "    return [v_i - w_i for v_i, w_i in zip(v,w)]\n",
    "\n",
    "def vector_sum(vectors):\n",
    "    return reduce(vector_add, vectors)\n",
    "\n",
    "def scalar_multiply(c, v):\n",
    "    return [c * v_i for v_i in v]\n",
    "\n",
    "def vector_mean(vectors):\n",
    "    \"\"\"compute the vector whose i-th element is the mean of the\n",
    "    i-th elements of the input vectors\"\"\"\n",
    "    n = len(vectors)\n",
    "    return scalar_multiply(1/n, vector_sum(vectors))\n",
    "\n",
    "def dot(v, w):\n",
    "    \"\"\"v_1 * w_1 + ... + v_n * w_n\"\"\"\n",
    "    return sum(v_i * w_i for v_i, w_i in zip(v, w))\n",
    "\n",
    "def sum_of_squares(v):\n",
    "    \"\"\"v_1 * v_1 + ... + v_n * v_n\"\"\"\n",
    "    return dot(v, v)\n",
    "\n",
    "def magnitude(v):\n",
    "    return math.sqrt(sum_of_squares(v))\n",
    "\n",
    "def squared_distance(v, w):\n",
    "    return sum_of_squares(vector_subtract(v, w))\n",
    "\n",
    "def distance(v, w):\n",
    "   return math.sqrt(squared_distance(v, w))\n",
    "\n",
    "#\n",
    "# functions for working with matrices\n",
    "#\n",
    "\n",
    "def shape(A):\n",
    "    num_rows = len(A)\n",
    "    num_cols = len(A[0]) if A else 0\n",
    "    return num_rows, num_cols\n",
    "\n",
    "def get_row(A, i):\n",
    "    return A[i]\n",
    "\n",
    "def get_column(A, j):\n",
    "    return [A_i[j] for A_i in A]\n",
    "\n",
    "def make_matrix(num_rows, num_cols, entry_fn):\n",
    "    \"\"\"returns a num_rows x num_cols matrix\n",
    "    whose (i,j)-th entry is entry_fn(i, j)\"\"\"\n",
    "    return [[entry_fn(i, j) for j in range(num_cols)]\n",
    "            for i in range(num_rows)]\n",
    "\n",
    "def is_diagonal(i, j):\n",
    "    \"\"\"1's on the 'diagonal', 0's everywhere else\"\"\"\n",
    "    return 1 if i == j else 0\n",
    "\n",
    "identity_matrix = make_matrix(5, 5, is_diagonal)\n",
    "\n",
    "#          user 0  1  2  3  4  5  6  7  8  9\n",
    "#\n",
    "friendships = [[0, 1, 1, 0, 0, 0, 0, 0, 0, 0], # user 0\n",
    "               [1, 0, 1, 1, 0, 0, 0, 0, 0, 0], # user 1\n",
    "               [1, 1, 0, 1, 0, 0, 0, 0, 0, 0], # user 2\n",
    "               [0, 1, 1, 0, 1, 0, 0, 0, 0, 0], # user 3\n",
    "               [0, 0, 0, 1, 0, 1, 0, 0, 0, 0], # user 4\n",
    "               [0, 0, 0, 0, 1, 0, 1, 1, 0, 0], # user 5\n",
    "               [0, 0, 0, 0, 0, 1, 0, 0, 1, 0], # user 6\n",
    "               [0, 0, 0, 0, 0, 1, 0, 0, 1, 0], # user 7\n",
    "               [0, 0, 0, 0, 0, 0, 1, 1, 0, 1], # user 8\n",
    "               [0, 0, 0, 0, 0, 0, 0, 0, 1, 0]] # user 9\n",
    "\n",
    "#####\n",
    "# DELETE DOWN\n",
    "#\n",
    "\n",
    "\n",
    "def matrix_add(A, B):\n",
    "    if shape(A) != shape(B):\n",
    "        raise ArithmeticError(\"cannot add matrices with different shapes\")\n",
    "\n",
    "    num_rows, num_cols = shape(A)\n",
    "    def entry_fn(i, j): return A[i][j] + B[i][j]\n",
    "\n",
    "    return make_matrix(num_rows, num_cols, entry_fn)\n",
    "\n",
    "\n",
    "def make_graph_dot_product_as_vector_projection(plt):\n",
    "\n",
    "    v = [2, 1]\n",
    "    w = [math.sqrt(.25), math.sqrt(.75)]\n",
    "    c = dot(v, w)\n",
    "    vonw = scalar_multiply(c, w)\n",
    "    o = [0,0]\n",
    "\n",
    "    plt.arrow(0, 0, v[0], v[1],\n",
    "              width=0.002, head_width=.1, length_includes_head=True)\n",
    "    plt.annotate(\"v\", v, xytext=[v[0] + 0.1, v[1]])\n",
    "    plt.arrow(0 ,0, w[0], w[1],\n",
    "              width=0.002, head_width=.1, length_includes_head=True)\n",
    "    plt.annotate(\"w\", w, xytext=[w[0] - 0.1, w[1]])\n",
    "    plt.arrow(0, 0, vonw[0], vonw[1], length_includes_head=True)\n",
    "    plt.annotate(u\"(v•w)w\", vonw, xytext=[vonw[0] - 0.1, vonw[1] + 0.1])\n",
    "    plt.arrow(v[0], v[1], vonw[0] - v[0], vonw[1] - v[1],\n",
    "              linestyle='dotted', length_includes_head=True)\n",
    "    plt.scatter(*zip(v,w,o),marker='.')\n",
    "    plt.axis('equal')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from collections import Counter\n",
    "#from linear_algebra import sum_of_squares, dot\n",
    "import math\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "num_friends = [100,49,41,40,25,21,21,19,19,18,18,16,15,15,15,15,14,14,13,13,13,13,12,12,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,8,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def make_friend_counts_histogram(plt):\n",
    "    friend_counts = Counter(num_friends)\n",
    "    xs = range(101)\n",
    "    ys = [friend_counts[x] for x in xs]\n",
    "    plt.bar(xs, ys)\n",
    "    plt.axis([0,101,0,25])\n",
    "    plt.title(\"Histogram of Friend Counts\")\n",
    "    plt.xlabel(\"# of friends\")\n",
    "    plt.ylabel(\"# of people\")\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nSUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fe4111f1278>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "make_friend_counts_histogram(plt)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "num_points = len(num_friends)               # 204"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "largest_value = max(num_friends)            # 100\n",
    "smallest_value = min(num_friends)           # 1\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "sorted_values = sorted(num_friends)\n",
    "smallest_value = sorted_values[0]           # 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "second_smallest_value = sorted_values[1]    # 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "second_largest_value = sorted_values[-2]    # 49"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# this isn't right if you don't from __future__ import division\n",
    "def mean(x):\n",
    "    return sum(x) / len(x)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def median(v):\n",
    "    \"\"\"finds the 'middle-most' value of v\"\"\"\n",
    "    n = len(v)\n",
    "    sorted_v = sorted(v)\n",
    "    midpoint = n // 2\n",
    "\n",
    "    if n % 2 == 1:\n",
    "        # if odd, return the middle value\n",
    "        return sorted_v[midpoint]\n",
    "    else:\n",
    "        # if even, return the average of the middle values\n",
    "        lo = midpoint - 1\n",
    "        hi = midpoint\n",
    "        return (sorted_v[lo] + sorted_v[hi]) / 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def quantile(x, p):\n",
    "    \"\"\"returns the pth-percentile value in x\"\"\"\n",
    "    p_index = int(p * len(x))\n",
    "    return sorted(x)[p_index]\n",
    "\n",
    "\n",
    "def mode(x):\n",
    "    \"\"\"returns a list, might be more than one mode\"\"\"\n",
    "    counts = Counter(x)\n",
    "    max_count = max(counts.values())\n",
    "    return [x_i for x_i, count in counts.items()\n",
    "            if count == max_count]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# \"range\" already means something in Python, so we'll use a different name\n",
    "def data_range(x):\n",
    "    return max(x) - min(x)\n",
    "\n",
    "def de_mean(x):\n",
    "    \"\"\"translate x by subtracting its mean (so the result has mean 0)\"\"\"\n",
    "    x_bar = mean(x)\n",
    "    return [x_i - x_bar for x_i in x]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def variance(x):\n",
    "    \"\"\"assumes x has at least two elements\"\"\"\n",
    "    n = len(x)\n",
    "    deviations = de_mean(x)\n",
    "    return sum_of_squares(deviations) / (n - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def standard_deviation(x):\n",
    "    return math.sqrt(variance(x))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def interquartile_range(x):\n",
    "    return quantile(x, 0.75) - quantile(x, 0.25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "daily_minutes = [1,68.77,51.25,52.08,38.36,44.54,57.13,51.4,41.42,31.22,34.76,54.01,38.79,47.59,49.1,27.66,41.03,36.73,48.65,28.12,46.62,35.57,32.98,35,26.07,23.77,39.73,40.57,31.65,31.21,36.32,20.45,21.93,26.02,27.34,23.49,46.94,30.5,33.8,24.23,21.4,27.94,32.24,40.57,25.07,19.42,22.39,18.42,46.96,23.72,26.41,26.97,36.76,40.32,35.02,29.47,30.2,31,38.11,38.18,36.31,21.03,30.86,36.07,28.66,29.08,37.28,15.28,24.17,22.31,30.17,25.53,19.85,35.37,44.6,17.23,13.47,26.33,35.02,32.09,24.81,19.33,28.77,24.26,31.98,25.73,24.86,16.28,34.51,15.23,39.72,40.8,26.06,35.76,34.76,16.13,44.04,18.03,19.65,32.62,35.59,39.43,14.18,35.24,40.13,41.82,35.45,36.07,43.67,24.61,20.9,21.9,18.79,27.61,27.21,26.61,29.77,20.59,27.53,13.82,33.2,25,33.1,36.65,18.63,14.87,22.2,36.81,25.53,24.62,26.25,18.21,28.08,19.42,29.79,32.8,35.99,28.32,27.79,35.88,29.06,36.28,14.1,36.63,37.49,26.9,18.58,38.48,24.48,18.95,33.55,14.24,29.04,32.51,25.63,22.22,19,32.73,15.16,13.9,27.2,32.01,29.27,33,13.74,20.42,27.32,18.23,35.35,28.48,9.08,24.62,20.12,35.26,19.92,31.02,16.49,12.16,30.7,31.22,34.65,13.13,27.51,33.2,31.57,14.1,33.42,17.44,10.12,24.42,9.82,23.39,30.93,15.03,21.67,31.09,33.29,22.61,26.89,23.48,8.38,27.81,32.35,23.84]\n",
    "\n",
    "def covariance(x, y):\n",
    "    n = len(x)\n",
    "    return dot(de_mean(x), de_mean(y)) / (n - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "covariance(num_friends, daily_minutes)\n",
    "\n",
    "\n",
    "# In[22]:\n",
    "\n",
    "def correlation(x, y):\n",
    "    stdev_x = standard_deviation(x)\n",
    "    stdev_y = standard_deviation(y)\n",
    "    if stdev_x > 0 and stdev_y > 0:\n",
    "        return covariance(x, y) / stdev_x / stdev_y\n",
    "    else:\n",
    "        return 0 # if no variation, correlation is zero"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "correlation(num_friends, daily_minutes)\n",
    "\n",
    "\n",
    "# In[24]:\n",
    "\n",
    "outlier = num_friends.index(100) # index of outlier\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "num_friends_good = [x\n",
    "                    for i, x in enumerate(num_friends)\n",
    "                    if i != outlier]\n",
    "\n",
    "\n",
    "# In[26]:\n",
    "\n",
    "daily_minutes_good = [x\n",
    "                      for i, x in enumerate(daily_minutes)\n",
    "                      if i != outlier]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5736792115665573"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "correlation(num_friends_good, daily_minutes_good)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "num_points 204\n",
      "largest value 100\n",
      "smallest value 1\n",
      "second_smallest_value 1\n",
      "second_largest_value 49\n",
      "mean(num_friends) 7.333333333333333\n",
      "median(num_friends) 6.0\n",
      "quantile(num_friends, 0.10) 1\n",
      "quantile(num_friends, 0.25) 3\n",
      "quantile(num_friends, 0.75) 9\n",
      "quantile(num_friends, 0.90) 13\n",
      "mode(num_friends) [6, 1]\n",
      "data_range(num_friends) 99\n",
      "variance(num_friends) 81.54351395730716\n",
      "standard_deviation(num_friends) 9.03014473623248\n",
      "interquartile_range(num_friends) 6\n",
      "covariance(num_friends, daily_minutes) 22.425435139573064\n",
      "correlation(num_friends, daily_minutes) 0.24736957366478218\n",
      "correlation(num_friends_good, daily_minutes_good) 0.5736792115665573\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "# In[28]:\n",
    "\n",
    "#if __name__ == \"__main__\":\n",
    "\n",
    "print(\"num_points\", len(num_friends))\n",
    "print(\"largest value\", max(num_friends))\n",
    "print(\"smallest value\", min(num_friends))\n",
    "print(\"second_smallest_value\", sorted_values[1])\n",
    "print(\"second_largest_value\", sorted_values[-2]  )\n",
    "print(\"mean(num_friends)\", mean(num_friends))\n",
    "print(\"median(num_friends)\", median(num_friends))\n",
    "print(\"quantile(num_friends, 0.10)\", quantile(num_friends, 0.10))\n",
    "print(\"quantile(num_friends, 0.25)\", quantile(num_friends, 0.25))\n",
    "print(\"quantile(num_friends, 0.75)\", quantile(num_friends, 0.75))\n",
    "print(\"quantile(num_friends, 0.90)\", quantile(num_friends, 0.90))\n",
    "print(\"mode(num_friends)\", mode(num_friends))\n",
    "print(\"data_range(num_friends)\", data_range(num_friends))\n",
    "print(\"variance(num_friends)\", variance(num_friends))\n",
    "print(\"standard_deviation(num_friends)\", standard_deviation(num_friends))\n",
    "print(\"interquartile_range(num_friends)\", interquartile_range(num_friends))\n",
    "\n",
    "print(\"covariance(num_friends, daily_minutes)\", covariance(num_friends, daily_minutes))\n",
    "print(\"correlation(num_friends, daily_minutes)\", correlation(num_friends, daily_minutes))\n",
    "print(\"correlation(num_friends_good, daily_minutes_good)\", correlation(num_friends_good, daily_minutes_good))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
